package com.hejia.alauda.service;

import static com.hejia.alauda.event.EventConstant.MONGODB_KEY_USER_YOUKU_CARD;
import static com.hejia.alauda.utils.Utils.MYSQL_DATE_FORMAT;
import static com.hejia.alauda.utils.Utils.formatDate;
import static com.hejia.alauda.utils.Utils.formatDateTime;
import static com.hejia.alauda.utils.Utils.isH5;
import static com.hejia.alauda.utils.Utils.isVersion10;
import static java.lang.Integer.MAX_VALUE;
import static java.util.Calendar.getInstance;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.replace;
import static org.apache.commons.lang3.StringUtils.trimToEmpty;
import static org.apache.commons.lang3.time.DateFormatUtils.ISO_TIME_NO_T_FORMAT;
import static org.apache.commons.lang3.time.DateUtils.addDays;
import static org.apache.commons.lang3.time.DateUtils.addMinutes;
import static org.springframework.util.CollectionUtils.arrayToList;
import static org.springframework.util.NumberUtils.parseNumber;
import static org.springframework.util.ObjectUtils.isEmpty;
import static org.springframework.util.StringUtils.quoteIfString;

import java.io.IOException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.TimeZone;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bson.types.ObjectId;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.dao.DataAccessException;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ReflectionUtils;

import com.hejia.alauda.entity.Address;
import com.hejia.alauda.entity.Award;
import com.hejia.alauda.entity.Balance;
import com.hejia.alauda.entity.BenefitsCode;
import com.hejia.alauda.entity.BonusReceive;
import com.hejia.alauda.entity.GewaraTicket;
import com.hejia.alauda.entity.Invitation;
import com.hejia.alauda.entity.OrderSerial;
import com.hejia.alauda.entity.Parameter;
import com.hejia.alauda.entity.Popularize;
import com.hejia.alauda.entity.Qualification;
import com.hejia.alauda.entity.SaleNotify;
import com.hejia.alauda.entity.User;
import com.hejia.alauda.entity.VerificationIp;
import com.hejia.alauda.entity.VerificationUserAgent;
import com.hejia.alauda.entity.example.AddressExample;
import com.hejia.alauda.entity.example.BonusReceiveExample;
import com.hejia.alauda.entity.example.BonusRecordExample;
import com.hejia.alauda.entity.example.FinancingExample;
import com.hejia.alauda.entity.example.InvitationExample;
import com.hejia.alauda.entity.example.PopularizeExample;
import com.hejia.alauda.entity.example.QualificationExample;
import com.hejia.alauda.entity.example.SaleNotifyExample;
import com.hejia.alauda.event.EventConstant;
import com.hejia.alauda.event.MessageEvent;
import com.hejia.alauda.mongodb.IwxTicket;
import com.hejia.alauda.mongodb.KeyValue;
import com.hejia.alauda.persistence.mybatis.AddressMapper;
import com.hejia.alauda.persistence.mybatis.BalanceMapper;
import com.hejia.alauda.persistence.mybatis.BalanceOperationMapper;
import com.hejia.alauda.persistence.mybatis.BonusReceiveMapper;
import com.hejia.alauda.persistence.mybatis.BonusRecordMapper;
import com.hejia.alauda.persistence.mybatis.FinancingMapper;
import com.hejia.alauda.persistence.mybatis.InterestMapper;
import com.hejia.alauda.persistence.mybatis.InvitationMapper;
import com.hejia.alauda.persistence.mybatis.OrderMapper;
import com.hejia.alauda.persistence.mybatis.ParameterMapper;
import com.hejia.alauda.persistence.mybatis.ProductMapper;
import com.hejia.alauda.persistence.mybatis.QualificationMapper;
import com.hejia.alauda.persistence.mybatis.SaleNotifyMapper;
import com.hejia.alauda.persistence.mybatis.UserMapper;
import com.hejia.alauda.utils.Encryption;
import com.hejia.alauda.utils.HttpRequest;
import com.hejia.alauda.utils.Pager;
import com.hejia.alauda.utils.Utils;
import com.hejia.hermes.entity.SMS;
import com.hejia.hermes.service.SMSService;

/**
 * Created by Johnny(johnny@hejiajinrong.com) on 14-9-5.
 */

@Service
// @Deprecated
public class CommonServiceImpl implements CommonService , ApplicationContextAware{

	protected static Log logger = LogFactory.getLog(CommonServiceImpl.class);

	protected static SimpleDateFormat formatter = new SimpleDateFormat("yyMMdd");

	public static ApplicationContext applicationContext = null;
	
	public static boolean devMode = false;

	public static final Object lock = new Object();
	
	public static final Object agreementlock = new Object();

	static Map<String, Object> FLASH_SALE_CONFIG = null;

	@Resource
	private ProductMapper productMapper;

	@Resource
	private UserService userService;

	@Resource
	private RedisTemplate<String, Object> redisTemplate;

	@Resource
	private InterestMapper interestMapper;

	@Resource
	private BalanceMapper balanceMapper;

	@Resource
	private BalanceOperationMapper balanceOperationMapper;

	@Resource
	private ConfigureService configureService;

	@Resource
	private BonusReceiveMapper bonusReceiveMapper;

	@Resource
	private BonusRecordMapper bonusRecordMapper;

	@Resource
	private InvitationMapper invitationMapper;

	@Resource
	private ApiService apiService;

	@Resource
	private PopularizeService popularizeService;

	@Resource
	private MongoTemplate mongoTemplate;

	@Resource
	private FinancingMapper financingMapper;

	@Resource
	private UserMapper userMapper;

	@Resource
	private AddressMapper addressMapper;

	@Resource
	private QualificationMapper qualificationMapper;
	
	@Resource
	private OrderMapper orderMapper;

	@Resource(name = "sendSMS")
	private SMSService smsService;
	
	@Resource
	private ParameterMapper parameterMapper;
	
	@Resource
	private SaleNotifyMapper saleNotifyMapper;

	@Resource
	private BalanceAndFinancingService balanceAndFinancingService;

	public CommonServiceImpl() {
		System.setProperty("user.timezone", "GMT+8");
		TimeZone.setDefault(TimeZone.getTimeZone("GMT+8"));
		logger.info("时区设置成功。");
	}

	// TODO 把下一个数据放在mongo之类的里面，防止重复生成
	@Override
	public String getProductSerial() {
		SimpleDateFormat formatter = new SimpleDateFormat("yyMMdd");
		String date = formatter.format(new Date());
		String random = new Integer(new Random().nextInt(9999)).toString();
		return "EP" + date + complemented(random, 4);
	}
	
	@Override
	public String getAgreementSerial(){
		return getAgreementSerial(null);
	}
	
	@Override
	public String getAgreementSerial(String date) {
		Date now = new Date();
		if(StringUtils.isBlank(date)){
			date = formatter.format(now);
		}
		
		synchronized (agreementlock) {
			// SimpleDateFormat formatter = new SimpleDateFormat("yyMMdd");
			
			for (int i = 0; i < MAX_VALUE; i++) {
				String random = new Integer(new Random().nextInt(999999)).toString();
				String serial = "AG" + date + complemented(random, 6);
				long count = mongoTemplate.count(new Query(new Criteria("serial").is(serial)), OrderSerial.class);
				if (count > 0) {
					logger.error("=====================>serial_count:" + count);
					logger.error("=====================>serial:" + serial);
				}
				if (count == 0) {
					OrderSerial orderSerial = new OrderSerial();
					orderSerial.setId(new ObjectId());
					orderSerial.setCreateDate(now);
					orderSerial.setSerial(serial);
					mongoTemplate.save(orderSerial);
					return serial;
				}
			}
			return "AG" + new ObjectId().toHexString();
		}
	}
	
	@Override
	public String getOrderSerial() {
		synchronized (lock) {
			// SimpleDateFormat formatter = new SimpleDateFormat("yyMMdd");
			Date now = new Date();
			String date = formatter.format(now);
			for (int i = 0; i < MAX_VALUE; i++) {
				String random = new Integer(new Random().nextInt(999999)).toString();
				String serial = "DD" + date + complemented(random, 6);
				/* mongodb里查询是否有重复生成过的订单号 */
				long count = mongoTemplate.count(new Query(new Criteria("serial").is(serial)), OrderSerial.class);
				if (count > 0) {
					logger.error("=====================>serial_count:" + count);
					logger.error("=====================>serial:" + serial);
				}
				if (count == 0) {
					OrderSerial orderSerial = new OrderSerial();
					orderSerial.setId(new ObjectId());
					orderSerial.setCreateDate(now);
					orderSerial.setSerial(serial);
					mongoTemplate.save(orderSerial);
					return serial;
				}
			}
			return "DD" + new ObjectId().toHexString();
		}
	}

	// 补全
	// TODO 放入工具类
	private static String complemented(String random, int length) {
		StringBuilder builder = new StringBuilder();
		for (int i = 0; i < length - random.length(); i++)
			builder.append("0");
		return builder.append(random).toString();
	}

	@Override
	public Map<String, Object> getAssets(User user,String os, String version) {
		Balance balance = userService.findUserBalance(user.getId());
//		List<Financing> list = null;
//		try {
//			list = financingMapper.findFinancingListByUser(user.getId());
//		} catch (Exception e) {
//			FinancingExample example = new FinancingExample();
//			example.appendCriterion("user_id=", user.getId());
//			list = balanceAndFinancingService.findFinancingByExample(example, null);
//		}
//		FinancingExample example = new FinancingExample();
//		example.appendCriterion("user_id=", user.getId());
//		List<Financing> list = balanceAndFinancingService.findFinancingByExample(example, null);
//		List<Financing> list = financingMapper.findFinancingListByUser(user.getId());
		Map<String, Object> userAssets = financingMapper.findAssetsByUser(user.getId());
		
		Map<String, Object> result = new HashMap<String, Object>();

		BigDecimal assets = new BigDecimal(0);// 总资产
		BigDecimal income = new BigDecimal(0);// 累计收益
		BigDecimal interest = new BigDecimal(0);// 当前收益
		List<Long> financingIdList = new ArrayList<Long>();
		if(userAssets!=null){
			if(userAssets.get("assets")!=null){
				assets = (BigDecimal)userAssets.get("assets");
			}
			if(userAssets.get("interest")!=null){
				interest = (BigDecimal)userAssets.get("interest");
			}
			if(userAssets.get("income")!=null){
				income = (BigDecimal)userAssets.get("income");
			}
		}
		if(isVersion10(os, version) || isH5(os)){
			result.put(
					"assets",
					assets.add(interest));// 总资产
		} else {
			result.put(
					"assets",
					assets.add(interest).add(new BigDecimal("" + balance.getRedEnvelope()))
							.add(findRedEnvelopeSumByUser(user)));// 总资产
		}
		result.put("income", income);// 累计收益
		result.put("interest", interest);// 当前收益
		result.put("redEnvelope", new BigDecimal("" + balance.getRedEnvelope()));// 总红包
		result.put("yesterdayInterest", "0.00");
		
		// 查询昨日收益
		String key = "yesterday_interest_" + user.getId() + "_" + formatDate(new Date());
		String yi = (String) redisTemplate.opsForValue().get(key);
		if (isNotBlank(yi)) {
			result.put("yesterdayInterest", yi);
		} else {
			// 查询昨日收益
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("user_id", user.getId());// 用户ID
			params.put("valueDate", new java.sql.Date(addDays(getInstance().getTime(), -1).getTime()));// 昨日的字符串
			try {
				result.put("yesterdayInterest", interestMapper.findInterestByDay(params).toString());
			} catch (Exception e) {
				result.put("yesterdayInterest", "0.00");
			}
			redisTemplate.opsForValue().set(key, result.get("yesterdayInterest"));
			redisTemplate.expire(key, 15 * 60, TimeUnit.SECONDS);
		}
		return result;
	}

	@Override
	public void setLoginFailedConunt(final String mobile) {
		redisTemplate.execute(new SessionCallback<Integer>() {
			@Override
			public Integer execute(RedisOperations redisOperations) throws DataAccessException {
				BoundValueOperations operations = redisOperations.boundValueOps("password_faild_count_" + mobile);
				Integer count = (Integer) operations.get();
				if (count == null) {
					count = 0;
				}
				operations.set(count + 1);
				operations.expireAt(addMinutes(getInstance().getTime(), 15));
				return null;
			}
		});
	}

	@Override
	public Integer getLoginFailedConunt(final String mobile) {
		return redisTemplate.execute(new SessionCallback<Integer>() {
			@Override
			public Integer execute(RedisOperations redisOperations) throws DataAccessException {
				BoundValueOperations operations = redisOperations.boundValueOps("password_faild_count_" + mobile);
				return operations.get() != null ? (Integer) operations.get() : 0;
			}
		});
	}

	@Override
	public void clearLoginFailedConunt(String mobile) {
		redisTemplate.delete("password_faild_count_" + mobile);
	}

	@Override
	public void setMobileSendMessage(String mobile) {
		redisTemplate.opsForValue().set("Mobile_Send_Message_" + mobile, "Send message OK");
		redisTemplate.expire("Mobile_Send_Message_" + mobile, 30, SECONDS);
	}

	@Override
	public Object getMobileSendMessage(String mobile) {
		return redisTemplate.opsForValue().get("Mobile_Send_Message_" + mobile);
	}

	@Override
	public void initializing() {
//		List<Balance> list = balanceMapper.selectByExample(new BalanceExample(), null);
//		if (!isEmpty(list)) {
//			for (Balance balance : list) {
//				if (balanceOperationMapper.findCountByBalance(balance) == 0) {
//					BalanceOperation operation = new BalanceOperation();
//					operation.setCreateDate(new Date());
//					operation.setModifyDate(operation.getCreateDate());
//					operation.setBalance(balance);
//					operation.setAmount(new BigDecimal("50"));
//					operation.setType(BalanceOperation.Type.RED_ENVELOPE);
//					balanceOperationMapper.insert(operation);
//					if (balance.getRedEnvelope() <= 0) {
//						operation = new BalanceOperation();
//						operation.setCreateDate(new Date());
//						operation.setModifyDate(operation.getCreateDate());
//						operation.setBalance(balance);
//						operation.setAmount(new BigDecimal("-50"));
//						operation.setType(BalanceOperation.Type.PAYMENT);
//						balanceOperationMapper.insert(operation);
//					}
//				}
//			}
//		}
	}

	@Override
	public String getAccessToken(String appid, String secret) {
		String access_token = (String) redisTemplate.opsForValue().get("weixin_access_token");
		if (isNotBlank(access_token)) {
			return access_token;
		}
		String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret="
				+ secret;
		try {
			Map<String, Object> result = Utils.getInstance().readValue(HttpRequest.httpGet(url, null), Map.class);
			access_token = (String) result.get("access_token");
			redisTemplate.opsForValue().set("weixin_access_token", access_token);
			redisTemplate.expire("weixin_access_token", 7200, SECONDS);
		} catch (JsonParseException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return access_token;
	}

	@Override
	public String getTicket(String access_token) {
		String jsapi_ticket = (String) redisTemplate.opsForValue().get("weixin_jsapi_ticket");
		if (isNotBlank(jsapi_ticket)) {
			return jsapi_ticket;
		}
		String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + access_token + "&type=jsapi";
		try {
			Map<String, Object> result = Utils.getInstance().readValue(HttpRequest.httpGet(url, null), Map.class);
			jsapi_ticket = (String) result.get("ticket");
			redisTemplate.opsForValue().set("weixin_jsapi_ticket", jsapi_ticket);
			redisTemplate.expire("weixin_jsapi_ticket", 7200, SECONDS);
		} catch (JsonParseException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return jsapi_ticket;
	}

	@Override
	public boolean isRookieHidden(User user) {
		if (user != null) {
			// FinancingExample example = new FinancingExample();
			// example.appendCriterion("user_id=", user.getId());
			// List<Financing> list =
			// transactionService.findFinancingByExample(example, null);

			return apiService.countFinancingByUser(user) > 0;
		}
		return false;
	}

	@Override
	public User isShared(User user) {
		// 先查询红包过期时间作为领取的截止时间
		Parameter parameter = configureService.getParameter(Parameter.Category.Activity, "2015_ShareBonusDeadline");
		if (parameter != null) {
			if (Utils.formatDateTime_i18n(getInstance()).compareTo(parameter.getValue()) < 0) {
				// 查询最早的从别人处领取到的红包记录
				BonusReceiveExample bonusReceiveExample = new BonusReceiveExample();
				bonusReceiveExample.appendCriterion("receiver=", user.getMobile());
				bonusReceiveExample.appendCriterion("receiver<>sharer");
				bonusReceiveExample.setOrderByClause("createDate");

				BonusReceive bonusReceive = bonusReceiveMapper.selectOneByExample(bonusReceiveExample);
				if (bonusReceive != null) {
					// 查询分享者是否在注册用户中
					User sharer = userService.findUserByMobile(bonusReceive.getSharer());
					if (sharer != null) {
						// 再查询分享红包者是否邀请过该用户
						InvitationExample invitationExample = new InvitationExample();
						invitationExample.appendCriterion("invitee_id=", user.getId());
						invitationExample.appendCriterion("inviter_id=", sharer.getId());
						return invitationMapper.countByExample(invitationExample) > 0 ? sharer : null;
					}
				}
			}
		}
		return null;
	}

	public BigDecimal findRedEnvelopeSumByUser(User user) {
		BigDecimal sum = bonusRecordMapper.findSumAmountByUser(user);
		return sum == null ? new BigDecimal("0") : sum;
	}

	@Override
	public boolean isQkmedia(User user) {
		return isChannel(user, "快客传媒");
	}

	public boolean isChannel(User user, String... channels) {
		if (user != null && !isEmpty(channels)) {
			String referee = trimToEmpty(user.getReferee());

			PopularizeExample example = new PopularizeExample();

			StringBuilder sb = new StringBuilder();
			sb.append('(');
			for (int i = 0; i < channels.length; i++) {
				sb.append("name like " + quoteIfString("%" + channels[i] + "%"));
				if (i < channels.length - 1) {
					sb.append(" OR ");
				}
			}
			sb.append(')');
			example.appendCriterion(sb.toString());

			List<Popularize> list = popularizeService.findPopularizesByExample(example);

			if (isNotBlank(referee) && list!=null && !list.isEmpty()) {
				for (Popularize item : list) {
					if (referee.indexOf(item.getSourceId()) > -1) {
						return true;
					}
				}
			}
		}
		return false;
	}

	// 爱无线官方WIFI点券活动
	@Override
	public long checkGewaraTicket() {
		long count = 0;
		try {
			List<String> list = Utils.getInstance().readValue(this.getClass().getResourceAsStream("/baihe.json"), List.class);
			setMongodbForValue("Baihe_Employee_Mobile_Number", list);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return count;
	}

	@Override
	public BenefitsCode findBenefitsCode(String code) {
		code = trimToEmpty(code);
		return mongoTemplate.findOne(new Query(new Criteria("code").is(code)), BenefitsCode.class);
	}

	public BenefitsCode findReceiveBenefitsByMobile(String mobile) {
		mobile = trimToEmpty(mobile);
		BenefitsCode benefitsCode = mongoTemplate.findOne(new Query(new Criteria("mobile").is(mobile)),
				BenefitsCode.class);
		return benefitsCode;
	}

	@Override
	public BenefitsCode findRandomBenefits(String mobile, String code) {
		synchronized (lock) {
			code = trimToEmpty(code);
			mobile = trimToEmpty(mobile);

			Random random = new Random();
			/**
			 * 查询各个奖的剩余次数
			 */
			int remaining_10000 = Utils.FINANCIAL_10000
					- (int) mongoTemplate.count(new Query(new Criteria("amount").is(10000)), BenefitsCode.class);
			int remaining_20000 = Utils.FINANCIAL_20000
					- (int) mongoTemplate.count(new Query(new Criteria("amount").is(20000)), BenefitsCode.class);
			int remaining_50000 = Utils.FINANCIAL_50000
					- (int) mongoTemplate.count(new Query(new Criteria("amount").is(50000)), BenefitsCode.class);
			int remaining_100000 = Utils.FINANCIAL_100000
					- (int) mongoTemplate.count(new Query(new Criteria("amount").is(100000)), BenefitsCode.class);
			logger.error("=======================>remaining_10000=" + remaining_10000);
			logger.error("=======================>remaining_20000=" + remaining_20000);
			logger.error("=======================>remaining_50000=" + remaining_50000);
			logger.error("=======================>remaining_100000=" + remaining_100000);
			BenefitsCode benefitsCode = mongoTemplate.findOne(new Query(new Criteria("code").is(code)),
					BenefitsCode.class);
			if (remaining_10000 > 0 || remaining_20000 > 0 || remaining_50000 > 0 || remaining_100000 > 0) {

				int total = remaining_10000 + remaining_20000 + remaining_50000 + remaining_100000;
				logger.error("=======================>total=" + total);
				int[] pool = new int[total];
				List<Integer> indexes = new ArrayList<Integer>();
				for (int i = 0; i < total; i++) {
					indexes.add(i);
				}
				for (int i = 0; i < remaining_10000; i++) {
					int index = random.nextInt(indexes.size());
					;
					pool[indexes.get(index)] = 10000;
					indexes.remove(index);
				}
				for (int i = 0; i < remaining_20000; i++) {
					int index = random.nextInt(indexes.size());
					;
					pool[indexes.get(index)] = 20000;
					indexes.remove(index);
				}
				for (int i = 0; i < remaining_50000; i++) {
					int index = random.nextInt(indexes.size());
					;
					pool[indexes.get(index)] = 50000;
					indexes.remove(index);
				}
				for (int i = 0; i < remaining_100000; i++) {
					int index = random.nextInt(indexes.size());
					;
					pool[indexes.get(index)] = 100000;
					indexes.remove(index);
				}
				Integer amount = pool[random.nextInt(pool.length)];
				logger.error("=======================>amount=" + amount);
				benefitsCode.setAmount(amount);
				benefitsCode.setCreateDate(Calendar.getInstance().getTime());
				benefitsCode.setMobile(mobile);
				mongoTemplate.save(benefitsCode);

				Map<String, Object> source = new HashMap<String, Object>();
				source.put("mobile", mobile);
				source.put("amount", amount);
				MessageEvent event = new MessageEvent(EventConstant.KEY_ANNUAL_MEETING_2015, source);
				applicationContext.publishEvent(event);
			}
			return benefitsCode;
		}
	}

	@Override
	public boolean isReceiveTwenty(User user) {
		if (user == null)
			return true;
		BonusRecordExample example = new BonusRecordExample();
		example.appendCriterion("type=" + quoteIfString("REGISTER2015"));
		example.appendCriterion("user_id=" + user.getId());
		int count = bonusRecordMapper.countByExample(example);
		return count > 0;
	}

	@Override
	public boolean isTradedBefore20150215(User user) {
		if (user != null && user.getCreateDate().getTime() < Utils.TIME_2015_02_15) {
			FinancingExample example = new FinancingExample();
			example.appendCriterion("user_id=", user.getId());
			example.appendCriterion("createDate<", new java.sql.Timestamp(Utils.TIME_2015_02_15));
			return financingMapper.countByExample(example) > 0;
		}
		return false;
	}

	@Override
	public int getGewaraTicket(final User user, Executor executor, boolean devMode) {
		synchronized (lock) {
			try {
				Parameter parameter = configureService.getParameter(Parameter.Category.Activity, "GewaraTicket");
				long time = parseNumber(parameter.getValue(), Long.class);

				Map<String, Object> params = new HashMap<String, Object>();
				params.put("user_id", user.getId());
				params.put("minTradeDate", new java.sql.Timestamp(time));
				BigDecimal amount = financingMapper.findTotalAmountByProperty(params);
				double total = amount == null ? 0 : amount.doubleValue();
				logger.info("======================>活动期间累计购买金额：" + total);
				if (total < 5000) {
					/**
					 * 活动期间累计购买金额小于5000的不给电影票
					 */
					return 8006;
				} else if (total < 10000) {
					/**
					 * 5000到10000以下的可以领一张
					 */
					Criteria criteria = new Criteria("mobile").is(user.getMobile());
					long count = mongoTemplate.count(new Query(criteria), GewaraTicket.class);
					if (count == 0) {
						final GewaraTicket gewaraTicket = getGewaraTicket(user.getMobile());
						if (gewaraTicket == null) {
							return 8007;
						}
						executor.execute(new GewaraTicketSender(gewaraTicket.getAccount(), gewaraTicket.getPassword(),
								user.getMobile(), devMode));
						return 0;
					} else {
						return 8009;
					}
				} else {
					/**
					 * 10000y以及以上的可以领两张
					 */
					Criteria criteria = new Criteria("mobile").is(user.getMobile());
					long count = mongoTemplate.count(new Query(criteria), GewaraTicket.class);
					if (count == 0) {
						final GewaraTicket gewaraTicket1 = getGewaraTicket(user.getMobile());
						final GewaraTicket gewaraTicket2 = getGewaraTicket(user.getMobile());

						if (gewaraTicket1 == null && gewaraTicket2 == null) {
							return 8007;
						}
						if (gewaraTicket1 != null) {
							executor.execute(new GewaraTicketSender(gewaraTicket1.getAccount(), gewaraTicket1
									.getPassword(), user.getMobile(), devMode));
						}
						if (gewaraTicket2 != null) {
							executor.execute(new GewaraTicketSender(gewaraTicket2.getAccount(), gewaraTicket2
									.getPassword(), user.getMobile(), devMode));
						}
						return 0;
					} else if (count == 1) {
						final GewaraTicket gewaraTicket = getGewaraTicket(user.getMobile());
						if (gewaraTicket == null) {
							return 8007;
						}
						executor.execute(new GewaraTicketSender(gewaraTicket.getAccount(), gewaraTicket.getPassword(),
								user.getMobile(), devMode));
						return 0;
					} else {
						return 8008;
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			return 2000;
		}
	}

	public GewaraTicket getGewaraTicket(String mobile) {
		synchronized (lock) {
			Criteria criteria = new Criteria("used").is(false);
			GewaraTicket gewaraTicket = mongoTemplate.findOne(new Query(criteria), GewaraTicket.class);
			if (gewaraTicket != null) {
				gewaraTicket.setUsed(true);
				gewaraTicket.setMobile(mobile);
				gewaraTicket.setReceiveTime(Calendar.getInstance().getTime());
				mongoTemplate.save(gewaraTicket);
			}
			return gewaraTicket;
		}
	}

	private class GewaraTicketSender implements Runnable {

		private String account;
		private String password;
		private String mobile;
		private boolean devMode;

		public GewaraTicketSender() {

		}

		public GewaraTicketSender(String account, String password, String mobile, boolean devMode) {
			super();
			this.account = account;
			this.password = password;
			this.mobile = mobile;
			this.devMode = devMode;
		}

		@Override
		public void run() {
			SMS sms = new SMS();
			sms.setMobile(this.mobile);
			sms.setMessage("尊敬的用户，感谢您参与活动，我们将赠送您一张格瓦拉电影票券，账号：" + this.account + "，密码：" + this.password
					+ "，可自行去格瓦拉官网兑换电影票，电影票券将在3月底到期。");
			sms.setChannel(this.devMode ? "alauda_activity" : "alauda_activity2");
			smsService.sendSMS(sms);
		}
	}

	@Override
	public List getMongoList() {
//		List<OrderSerial> list = mongoTemplate.find(new Query(new Criteria("track_id").is("hj_mm_TWFncGllX0Zlc3RpdmFs")), OrderSerial.class);
//		Map<String,Object> params = new LinkedHashMap<String, Object>();
//		params.put("orderNumbers", new DataHandler(list).convert(new RowMapper() {
//			
//			@Override
//			public Object mapRow(Object rs, int rowNum) {
//				OrderSerial os = (OrderSerial) rs;
//				return os.getSerial();
//			}
//		}));
//		return financingMapper.findTestFinancingByProperty(params);
		return mongoTemplate.find(new Query(new Criteria("type").is("WasuSeason3")), IwxTicket.class);
	}

	@Override
	public void setOpsForValue(String key, Object value, Date expired) {
		this.redisTemplate.opsForValue().set(key, value);
		if (expired != null) {
			this.redisTemplate.expireAt(key, expired);
		}
	}

	@Override
	public Object getOpsForValue(String key) {
		return this.redisTemplate.opsForValue().get(key);
	}

	@Override
	public void saveVerificationStatus(String ip, String userAgent, String url) {
		/* 记录IP访问数 */
		VerificationIp verificationIp = mongoTemplate.findOne(new Query(new Criteria("ip").is(ip).and("url").is(url)),
				VerificationIp.class);
		if (verificationIp == null) {
			verificationIp = new VerificationIp();
			verificationIp.setId(new ObjectId());
			verificationIp.setIp(ip);
			verificationIp.setUrl(url);
		}
		verificationIp.setCount(verificationIp.getCount() + 1);
		verificationIp.setDate(new Date());
		mongoTemplate.save(verificationIp);
		/* 记录UserAgent访问数 */
		VerificationUserAgent verificationUserAgent = mongoTemplate.findOne(
				new Query(new Criteria("userAgent").is(userAgent).and("url").is(url)), VerificationUserAgent.class);
		if (verificationUserAgent == null) {
			verificationUserAgent = new VerificationUserAgent();
			verificationUserAgent.setId(new ObjectId());
			verificationUserAgent.setUserAgent(userAgent);
			verificationUserAgent.setUrl(url);
		}
		verificationUserAgent.setCount(verificationUserAgent.getCount() + 1);
		verificationUserAgent.setDate(new Date());
		mongoTemplate.save(verificationUserAgent);
	}

	@Override
	public Pager<VerificationIp> getVerificationIpList(Pager<VerificationIp> pager) {
		pager.setList(mongoTemplate.find(new Query().with(new Sort(Direction.DESC, "date"))
				.skip(pager.getStartNumber()).limit(pager.getPageSize()), VerificationIp.class));
		pager.setTotalCount(new Long(mongoTemplate.count(new Query(), VerificationIp.class)).intValue());
		return pager;
	}

	@Override
	public Pager<VerificationUserAgent> getVerificationUserAgentList(Pager<VerificationUserAgent> pager) {
		pager.setList(mongoTemplate.find(new Query().with(new Sort(Direction.DESC, "date"))
				.skip(pager.getStartNumber()).limit(pager.getPageSize()), VerificationUserAgent.class));
		pager.setTotalCount(new Long(mongoTemplate.count(new Query(), VerificationUserAgent.class)).intValue());
		return pager;
	}

	@Override
	public boolean saveVerification(String id, Boolean disabled, String clazz) {
		if (isNotBlank(id) && disabled != null && isNotBlank(clazz)) {
			try {
				Class entityClass = Class.forName(clazz);
				Object target = mongoTemplate.findById(id, entityClass);
				if (target != null) {
					Method method = ReflectionUtils.findMethod(target.getClass(), "setDisable", Boolean.TYPE);
					if (method != null) {
						ReflectionUtils.invokeMethod(method, target, disabled);
						mongoTemplate.save(target);
						return true;
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return false;
	}

	@Override
	public VerificationIp getVerificationIp(String ip) {
		return mongoTemplate.findOne(new Query(new Criteria("ip").is(ip)), VerificationIp.class);
	}

	@Override
	public VerificationUserAgent getVerificationUserAgent(String userAgent) {
		return mongoTemplate.findOne(new Query(new Criteria("userAgent").is(userAgent)), VerificationUserAgent.class);
	}

	@Override
	public Qualification findQualificationByExample(QualificationExample example) {
		return qualificationMapper.selectOneByExample(example);
	}
	
	@Override
	public List<Qualification> findQualificationsByExample(QualificationExample example,Pager<Qualification> pager) {
		return qualificationMapper.selectByExample(example,pager);
	}

	@Override
	public List<Qualification> findQualificationsByExample(QualificationExample example) {
		List<Qualification> result = qualificationMapper.selectByExample(example, null);
		
		if (result == null || result.size() == 0) 
			result = Collections.emptyList();
		
		return result;
	}

	@Override
	public int insertQualification(Qualification qualification) {
		return qualificationMapper.insert(qualification);
	}

	@Override
	public int updateQualification(Qualification qualification) {
		return qualificationMapper.updateByPrimaryKey(qualification);
	}

	@Override
	public List<Qualification> findAwardsByUser(User user) {
		if (user == null)
			return Collections.EMPTY_LIST;
		QualificationExample example = new QualificationExample();
		example.appendCriterion("user_id=", user.getId());
		example.appendCriterion("type=", Qualification.TYPE_BONUS_20150310);
		example.appendCriterion("used=", true);
		example.appendCriterion("awardCode<>", Award.THANKS);
		return qualificationMapper.selectByExample(example, null);
	}

	@Override
	public Award luckydraw() {
		synchronized (lock) {
			List<Award> list = new ArrayList<Award>();
			for (int i = 0; i < 2500; i++) {
				list.add(Award.THANKS);
				list.add(Award.CREDIT_2000);
				// list.add(Award.CREDIT_10000);
			}
			try {
				if (FLASH_SALE_CONFIG == null) {
					FLASH_SALE_CONFIG = Utils.getInstance().readValue(
							this.getClass().getResourceAsStream("/FlashSaleConfig.json"), Map.class);
				}
				if (FLASH_SALE_CONFIG != null) {
					/* 格式化时间HHmmss */
					String time = replace(ISO_TIME_NO_T_FORMAT.format(getInstance()), ":", "");
					for (Award award : Award.values()) {
						if (FLASH_SALE_CONFIG.get(award.toString()) != null) {
							int awardCount = 0;
							Map<String, Integer> item = (Map<String, Integer>) FLASH_SALE_CONFIG.get(award.toString());
							List<String> keys = arrayToList(item.keySet().toArray());
							Collections.sort(keys);
							for (int k = keys.size() - 1; k >= 0; k--) {
								if (time.compareTo(keys.get(k)) >= 0) {
									awardCount = item.get(keys.get(k));
									break;
								}
							}
							if (awardCount > 0) {
								/* 查询该奖品总共被抽走了多少 */
								QualificationExample example = new QualificationExample();
								example.appendCriterion("`type`=", Qualification.TYPE_BONUS_20150310);
								example.appendCriterion("`awardCode`=", award.toString());
								example.appendCriterion(String.format(MYSQL_DATE_FORMAT, "createDate") + "=",
										formatDate(getInstance()));
								awardCount = awardCount - qualificationMapper.countByExample(example);
							}
							logger.info("=========================>award:" + award + ",awardCount:" + awardCount);
							if (awardCount > 0) {
								switch (award) {
								case IPAD_MINI:
									for (int i = 0; i < 25; i++) {
										list.add(Award.THANKS);
									}
									break;
								case DOGE_CUSHION:
									for (int i = 0; i < 200; i++) {
										list.add(award);
									}
									break;
								case AIR_CLEANER:
									for (int i = 0; i < 1050; i++) {
										list.add(award);
									}
									break;
								case SELFIESTICK:
									for (int i = 0; i < 1000; i++) {
										list.add(award);
									}
									break;
								case POWER_BANK:
									for (int i = 0; i < 225; i++) {
										list.add(award);
									}
									break;
								case CREDIT_10000:
									for (int i = 0; i < 2500; i++) {
										list.add(award);
									}
									break;
								default:
									break;
								}
								logger.info("=========================>list:" + list.size());
							} else {
								switch (award) {
								case IPAD_MINI:
									for (int i = 0; i < 25; i++) {
										list.add(Award.THANKS);
									}
									break;
								case DOGE_CUSHION:
									for (int i = 0; i < 200; i++) {
										list.add(Award.THANKS);
									}
									break;
								case AIR_CLEANER:
									for (int i = 0; i < 1050; i++) {
										list.add(Award.THANKS);
									}
									break;
								case SELFIESTICK:
									for (int i = 0; i < 1000; i++) {
										list.add(Award.THANKS);
									}
									break;
								case POWER_BANK:
									for (int i = 0; i < 225; i++) {
										list.add(Award.THANKS);
									}
									break;
								case CREDIT_10000:
									for (int i = 0; i < 2500; i++) {
										list.add(Award.THANKS);
									}
									break;
								default:
									break;
								}
								logger.info("=========================>list:" + list.size());
							}
						}
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			/* 类似扑克洗牌洗20次此列表 */
			for (int k = 0; k < 20; k++) {
				Collections.shuffle(list);
			}
			Random random = new Random();
			return list.get(random.nextInt(list.size()));
		}
	}

	@Override
	public Qualification findQualificationById(Long id) {
		return qualificationMapper.selectByPrimaryKey(id);
	}

	@Override
	public List findQualificationList() {
		return qualificationMapper.findQualificationList();
	}

	@Override
	public Address findAddressByExample(AddressExample example) {
		return addressMapper.selectOneByExample(example);
	}

	@Override
	public int insertAddress(Address address) {
		return addressMapper.insert(address);
	}

	@Override
	public int updateAddress(Address address) {
		return addressMapper.updateByPrimaryKey(address);

	}

	@Override
	public int findQualificationCountByExample(QualificationExample example) {
		return qualificationMapper.countByExample(example);
	}

	@Override
	public void checkMarchTrafficQualification(User user) {
		QualificationExample example = new QualificationExample();
		example.appendCriterion("`type`=", Qualification.TYPE_MARCH_TRAFFIC_20150328);
		example.appendCriterion("`user_id`=", user.getId());
		if (qualificationMapper.countByExample(example) <= 0) {
			Qualification qualification = new Qualification();
			qualification.setCreateDate(getInstance().getTime());
			qualification.setModifyDate(qualification.getCreateDate());
			qualification.setUser(user);
			qualification.setType(Qualification.TYPE_MARCH_TRAFFIC_20150328);
			qualification.setUsed(Boolean.FALSE);
			qualificationMapper.insert(qualification);
		}
	}

	@Override
	public List<GewaraTicket> findGewaraTicketByUser(String mobile) {
		return mongoTemplate.find(new Query(new Criteria("mobile").is(mobile)), GewaraTicket.class);
	}

	@Override
	public void setMongodbForValue(String key, Object value) {
		KeyValue keyValue = mongoTemplate.findOne(new Query(new Criteria("key").is(key)), KeyValue.class);
		if (keyValue == null) {
			keyValue = new KeyValue();
			keyValue.setId(new ObjectId());
			keyValue.setKey(key);
			keyValue.setValue(value);
			keyValue.setCreateDate(formatDateTime(getInstance()));
			keyValue.setModifyDate(keyValue.getCreateDate());
		} else {
			keyValue.setValue(value);
			keyValue.setModifyDate(formatDateTime(getInstance()));
		}
		mongoTemplate.save(keyValue);
	}

	@Override
	public Object getMongodbForValue(String key) {
		KeyValue keyValue = mongoTemplate.findOne(new Query(new Criteria("key").is(key)), KeyValue.class);
		return keyValue != null ? keyValue.getValue() : null;
	}
	
	public long getMongodbForCountByRegex(String regex){
		return mongoTemplate.count(new Query(new Criteria("key").regex(regex)), KeyValue.class);
	}

	@Override
	@Transactional(timeout = TransactionTimeout.THREE_SECOND)
	public void insertAddress(User user, String name, String mobile, String address) {
		AddressExample addressExample = new AddressExample();
		addressExample.appendCriterion("`user_id`=", user.getId());
		Address addressdb = this.findAddressByExample(addressExample);

		if (addressdb == null) {
			addressdb = new Address();
			addressdb.setCreateDate(Calendar.getInstance().getTime());
			addressdb.setUser(user);
		}

		addressdb.setMobile(mobile);
		addressdb.setAddress(address);
		addressdb.setName(name);
		addressdb.setModifyDate(Calendar.getInstance().getTime());

		if (addressdb.getId() == null) {
			this.insertAddress(addressdb);
		} else {
			this.updateAddress(addressdb);
		}
	}

	public void deleteMongodbForValue(String key) {
		KeyValue keyValue = mongoTemplate.findOne(new Query(new Criteria("key").is(key)), KeyValue.class);
		if (keyValue != null)
			mongoTemplate.remove(keyValue);
	}

	@Override
	public void deleteMongodbForExpiredDate() {
		mongoTemplate.remove(new Query(new Criteria("expiredDate").lte(formatDateTime(getInstance()))), KeyValue.class);
	}

	@Override
	public void setMongodbForValue(String key, Object value, Date expired) {
		KeyValue keyValue = mongoTemplate.findOne(new Query(new Criteria("key").is(key)), KeyValue.class);
		if (keyValue == null) {
			keyValue = new KeyValue();
			keyValue.setId(new ObjectId());
			keyValue.setKey(key);
			keyValue.setValue(value);
			keyValue.setCreateDate(formatDateTime(getInstance()));
			keyValue.setModifyDate(keyValue.getCreateDate());
			if (expired != null) {
				keyValue.setExpiredDate(formatDateTime(expired));
			}
		} else {
			keyValue.setValue(value);
			keyValue.setModifyDate(formatDateTime(getInstance()));
			if (expired != null) {
				keyValue.setExpiredDate(formatDateTime(expired));
			}
		}
		mongoTemplate.save(keyValue);
	}

	@Override
	public void setUserInvestmentsReaded(User user) {
		List<KeyValue> list = mongoTemplate.find(
				new Query(new Criteria("key")
						.regex("User_Financing_Redemption_" + user.getId()
								+ "_")), KeyValue.class);
		if (list != null && !list.isEmpty()) {
			for (KeyValue item : list) {
				item.setValue(true);
				mongoTemplate.save(item);
			}
		}
	}

	@Override
	public int test(Long id) {
		if(orderMapper.updateLockOrderById(id)>0){
			try {
				Thread.sleep(10000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			logger.info("=====================>处理完毕");
			orderMapper.updateReleaseOrderById(id);
		} else {
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return test(id);
		}
		return 0;
	}

	@Override
	public int caculateDateInterval(String date1, String date2) {
		return parameterMapper.calculateDateInterval(date1, date2);
	}

	@Override
	public void sendYoukuOrder(User user, Award award, String productId,
			String productName) {
		Date date = new Date();
		String dateStr = formatDate(date);
		String key = String.format(EventConstant.REDIS_KEY_USER_YOUKU_MESSAGE_COUNT, user.getMobile(), dateStr);
		Integer count = (Integer) redisTemplate.opsForValue().get(key);
		if(count == null)
			count = 0;
		if(count.intValue()>=5){
			switch (award) {
			case YOUKU_MONTH_CARD:
				sendYoukuCard(user, Award.YOUKU_MONTH_CARD_HEJIA);
				break;
			case YOUKU_SEASON_CARD:
				sendYoukuCard(user, Award.YOUKU_SEASON_CARD_HEJIA);
				break;
			default:
				sendYoukuCard(user, award);
				break;
			}
		}
		
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSSS");
		SimpleDateFormat format2 = new SimpleDateFormat("yyyyMMddHHmmss");
		
		Random random = new Random();
		String randomNumber = "" + random.nextInt(100000000);
		
		String serial = "hejia" + format.format(date) + complemented(randomNumber, 8);
		
		Map<String, String> params = new LinkedHashMap<String, String>();
    	params.put("transferId", serial);
    	params.put("transferTime", format2.format(date));
    	params.put("phoneNumber", user.getMobile());
    	params.put("telecomOper", "hejiajinrong");
    	params.put("resource", "resource_hejia");
    	params.put("productId", productId);
    	params.put("productName", productName);
    	params.put("action", "0");
    	params.put("paramList", "123");
    	params.put("sign", "c670b7a5bd2b8e8d8383c4cbf3b49b2f");
    	String sign = "transferId%stransferTime%sphoneNumber%stelecomOper%sresource%sproductId%sproductName%saction%sparamList%sykfm_sign_key%s";
    	
    	params.put("sign", Encryption.getMD5(String.format(sign, params.values().toArray())));
    	
    	setMongodbForValue(MONGODB_KEY_USER_YOUKU_CARD + user.getMobile() + "_" + serial, "100_准备发送");
    	redisTemplate.opsForValue().set(key, count+1);
    	redisTemplate.expireAt(key, addDays(date, 1));
    	Qualification qualification = new Qualification();
    	qualification.setCreateDate(date);
    	qualification.setModifyDate(date);
    	qualification.setUser(user);
    	qualification.setUsed(true);
    	qualification.setAward(award.getName());
    	qualification.setAwardCode(award.getCode());
    	qualification.setType(Qualification.TYPE_YOUKU_CARD_2015);
    	qualificationMapper.insert(qualification);
    	if (!"Mac OS X".equals(System.getProperty("os.name"))) {
	    	Map<String,Object> result = HttpRequest.sendYoukuRequest(params);
	    	if(result.size()>0){
	    		setMongodbForValue(MONGODB_KEY_USER_YOUKU_CARD + user.getMobile() + "_" + result.get("transferId"), result.get("returnCode") + "_" + result.get("returnMessage"));
	    	}
    	}
	}
	
	public boolean isYoukuInvite(User user) {
		InvitationExample example = new InvitationExample();
		example.appendCriterion("`type`=", Invitation.TYPE_YOUKU_2015);
		example.appendCriterion("`invitee_id`=", user.getId());
		return invitationMapper.countByExample(example)>0;
	}

	@Override
	public void sendYoukuCard(User user, Award award) {
		Date date = new Date();
		switch (award) {
		case YOUKU_MONTH_CARD_FOR_SHARE:
		case YOUKU_MONTH_CARD_HEJIA:
			IwxTicket ticket = mongoTemplate.findOne(new Query(new Criteria("type").is("YoukuMonth").and("used").is(false)), IwxTicket.class);
			if(ticket!=null){
				ticket.setUsed(true);
				ticket.setMobile(user.getMobile());
				mongoTemplate.save(ticket);
				
				userService.sendUniversalMessage(user.getMobile(), String.format("尊敬的%s用户您好，您的优酷会员卡密为%s，卡类型为月卡。登录vip.youku.com激活", user.getMobile(), ticket.getCode()), "alauda_activity");
				Qualification qualification = new Qualification();
		    	qualification.setCreateDate(date);
		    	qualification.setModifyDate(date);
		    	qualification.setUser(user);
		    	qualification.setUsed(true);
		    	qualification.setAward(award.getName());
		    	qualification.setAwardCode(award.getCode());
		    	qualification.setType(Qualification.TYPE_YOUKU_CARD_2015);
		    	qualificationMapper.insert(qualification);
			} //if
			break;
		case YOUKU_SEASON_CARD_HEJIA:
			ticket = mongoTemplate.findOne(new Query(new Criteria("type").is("YoukuSeason").and("used").is(false)), IwxTicket.class);
			if(ticket!=null){
				ticket.setUsed(true);
				ticket.setMobile(user.getMobile());
				mongoTemplate.save(ticket);
				//尊敬的18868726125用户您好，您的优酷会员卡的密码为V8D2ZMY9TT，卡类型为季卡。登录vip.youku.com激活
				userService.sendUniversalMessage(user.getMobile(), String.format("尊敬的%s用户您好，您的优酷会员卡密为%s，卡类型为季卡。登录vip.youku.com激活", user.getMobile(), ticket.getCode()), "alauda_activity");
				Qualification qualification = new Qualification();
		    	qualification.setCreateDate(date);
		    	qualification.setModifyDate(date);
		    	qualification.setUser(user);
		    	qualification.setUsed(true);
		    	qualification.setAward(award.getName());
		    	qualification.setAwardCode(award.getCode());
		    	qualification.setType(Qualification.TYPE_YOUKU_CARD_2015);
		    	qualificationMapper.insert(qualification);
			} //if
			break;
		default:
			break;
		}
		
		
	}

	@Override
	public IwxTicket createRedCode(Integer amount) {
		IwxTicket ticket = null;
		for(int i=0;i<Integer.MAX_VALUE;i++){
			String code = Encryption.getMD5(formatDate(new Date()) + new ObjectId().toHexString());
			long n = mongoTemplate.count(new Query(new Criteria("code").is(code).and("type").is("RedCode")), IwxTicket.class);
			if(n == 0){
				ticket = new IwxTicket();
				ticket.setCode(trimToEmpty(code));
				ticket.setCreateDate(formatDateTime(new Date()));
				ticket.setId(new ObjectId());
				ticket.setModifyDate(ticket.getCreateDate());
				ticket.setType("RedCode");
				ticket.setValue(amount);
				ticket.setUsed(false);
				mongoTemplate.insert(ticket);
				break;
			} else {
				continue;
			}
		}
		return ticket;
	}

	@Override
	public List<OrderSerial> getOrderSerialList(String track_id) {
		return this.mongoTemplate.find(new Query(new Criteria("track_id").is(track_id)), OrderSerial.class);
	}

	@Override
	public OrderSerial getOrderSerialByOrderNumber(String orderNumber) {
		return mongoTemplate.findOne(new Query(new Criteria("serial").is(orderNumber)), OrderSerial.class);
	}
	
	@Override
	public void saveMobileForSaleNotify(User user, String mobile){
		SaleNotify record = new SaleNotify();
		record.setUser(user);
		
		if(StringUtils.isBlank(mobile))
			mobile = user.getMobile();
		
		record.setMobile(mobile);
		saleNotifyMapper.insert(record);
	}
	
	@Override
	public boolean getSaleNofity(User user){
		if (user == null)
			return false;
		SaleNotifyExample example = new SaleNotifyExample();
		example.appendCriterion("user_id=", user.getId());
		example.appendCriterion("enable=1");
		return saleNotifyMapper.countByExample(example) > 0;
	}
	
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		logger.info("初始化applicationContext:" + applicationContext);
		CommonServiceImpl.applicationContext = applicationContext;
	}
	
	@Override
	public BigDecimal getProductCount(){
		BigDecimal count = productMapper.countProduct();
		return count == null?new BigDecimal(0):count;
	}
	
	@Override
	public BigDecimal getFinishedAmount(){
		BigDecimal amount = financingMapper.getFinishedAmount();
		return amount == null?new BigDecimal(0):amount;
	
	}
	
	public class DownloadCounter{
		long count;

		public long getCount() {
			return count;
		}

		public void setCount(long count) {
			this.count = count;
		}
		
		public void increase(){
			count++;
		}
	}

	@Override
	public DownloadCounter getDownloadCounts() {
		return   mongoTemplate.findOne(new Query(new Criteria("type").is("count")), DownloadCounter.class);
	}
	
	@Override
    public void updateDownloadCounts(DownloadCounter counter){
		Update update = new Update(); 
		update.set("count", counter.getCount());
		mongoTemplate.updateFirst(new Query(new Criteria("type").is("count")), update, DownloadCounter.class);
	}
	
	
}